package edu.suda.LoopCodePlus.webSocket;

import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
public class WsSessionManager {
    /**
     * 保存连接 session 的地方
     */
    //存储所有用户的连接
    private static ConcurrentHashMap<Integer, WebSocketSession> userSession=new ConcurrentHashMap<>();
    //存储在房间里面的用户
    private static ConcurrentHashMap<Integer, WebSocketSession> roomSession=new ConcurrentHashMap<>();
    //并为每个用户设立一个时间戳
    private static ConcurrentHashMap<Integer, HashMap<Integer, WebSocketSession>> SESSION_POOL=new ConcurrentHashMap<>();;
    private static ConcurrentHashMap<Integer, HashMap<Integer, WebSocketSession>> room=new ConcurrentHashMap<>();

    //初始化连接池
    public static void init(){
        System.out.println("初始化连接池");
        for(int i=0;i<20;i++){
            SESSION_POOL.put(i, new HashMap<Integer, WebSocketSession>());
        }
        System.out.println("初始化完成");
    }
    /**
     * 添加 session
     *
     *
     */
    // 添加 session当有新用户进来的时候
    public static Integer add(Integer point, Integer userId,WebSocketSession session) {
        System.out.println("将用户"+userId+"加入连接池");
        Integer key = point/1000;
        //遍历连接池，判断用户是否在某一个连接池的映射中
        if(userSession.containsKey(key)||roomSession.containsKey(userId)){
            System.out.println("用户已经在连接池或房间中");
            return 0;//用户已经在连接池或某个房间中
        }
        // 添加 session
        HashMap<Integer, WebSocketSession> sessionsForPoint = SESSION_POOL.computeIfAbsent(key, k -> new HashMap<>());
        // Add the session.
        sessionsForPoint.put(userId, session);
        userSession.put(userId, session);
        System.out.println("用户连接添加成功");
        return 1;    //用户已添加
    }

    public static Integer addRoom(Integer point, Integer userId,WebSocketSession session) {
        //判断用户是否已经在某个房间中，已经在的话，不允许重复加入
        if(roomSession.containsKey(userId)){
            System.out.println("用户已经在房间中，不允许再次加入");
            return 0;  //用户已经在某个房间中，不允许再加入
        }
        //否则,判断连接池中point映射中是否有两个用户
        if(SESSION_POOL.get(point/1000).size()==2){
            System.out.println("匹配连接池人数充足，匹配成功，将两名用户加入房间");
            //房间人数够了，将用户从连接池中删除，将两名用户加入房间中，房间id号为两名用户中后加入的userId
            room.put(userId, SESSION_POOL.get(point/1000));
            for(Integer id:SESSION_POOL.get(point/1000).keySet()){
                roomSession.put(id,userSession.get(id));
            }
            System.out.println("加入房间成功");
            SESSION_POOL.remove(point/1000);
            userSession.remove(point/1000);
            System.out.println("用户已从匹配连接池中删除");
            return 1;                  //两名用户已经从连接池中删除，添加到了房间中
        }
        else{
            System.out.println("匹配人数不足，继续等待");
            return 2;       //该房间还不足两人
        }
    }

    /**
     * 删除并同步关闭连接
     *
     *
     */
    public static void removeAndClose(Integer roomId) {
        System.out.println("比赛结束,将房间"+roomId+"中的用户移除");
        HashMap<Integer,WebSocketSession> sessions = room.get(roomId);
        //关闭连接
        for(Integer userId:sessions.keySet()){
            try {
                sessions.get(userId).close();
                roomSession.remove(userId);
                userSession.remove(userId);
                System.out.println("用户"+userId+"已关闭连接");
            } catch (IOException e) {
                System.out.println("用户"+userId+"关闭连接失败");
                e.printStackTrace();
            }
        }
        //将两名用户的房间删除
        room.remove(roomId);
        System.out.println("房间"+roomId+"已删除");
    }

    /**
     * 获得 session
     *
     * @param key
     * @return
     */
    public static WebSocketSession get(Integer key) {
        // 获得 session
        return userSession.get(key);
    }
    /*****
     * 获取房间中的用户
     */
    public static HashMap<Integer,WebSocketSession> getRoom(Integer roomId){
        return room.get(roomId);
    }

    /*****
     * 打印四个连接池状态
     */
    public static void print(){
        System.out.println("打印连接池状态");
        System.out.println("userSession:"+userSession);
        System.out.println("roomSession:"+roomSession);
        System.out.println("SESSION_POOL:"+SESSION_POOL);
        System.out.println("room:"+room);

    }
}



